/*
 * Middleware
 * Copyright (C) 2010/11
 * Riccardo Pulvirenti, Giuseppe Ravidà, Andrea Tino
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANDABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses
 */

/*!
 * File: task_descriptor.hpp
 */

#ifndef _TASK_DESCRIPTOR_HPP_
#define _TASK_DESCRIPTOR_HPP_

#include <iostream>
#include <string>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

//-----------------------------------------------------------------------------
// Enum, struct, aliases
namespace middleware {
typedef unsigned int TaskId;
typedef enum {
	kTaskExecutable = 0,
	kTaskBashCommand = 1
} TaskType;
typedef std::string TaskCommand;
typedef struct {
	friend class boost::serialization::access;
	/*!
	 * BOOST serialization function.
	 */
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version) {
		ar & machine_addr;
		ar & network_inet_ip;
		ar & network_inet_port;
	}
	/*!
	 * Members.
	 */
	std::string machine_addr; /* i.e. /usr/local/exec.out */
	std::string network_inet_ip; /* i.e. 157.23.12.198 */
	std::string network_inet_port; /* i.e. 16001 */
} TaskLinkage;
}
//-----------------------------------------------------------------------------
// Constants
namespace middleware {
/*!
 * Represents the maximun ID assignable to a task.
 */
const unsigned int kMaxTaskID = 16000;
/*!
 * Represents the minimum ID assignable to a task.
 */
const unsigned int kMinTaskID = 1;
}
//-----------------------------------------------------------------------------
// Class definitions
namespace middleware {
/*!
 * Defines all elements for a task.
 */
class TaskDescriptor {
public:
	/*!
	 * Builds a command task with no command, setting an arbitrary id.
	 */
	TaskDescriptor();
	/*!
	 * Builds an executable task.
	 */
	TaskDescriptor(TaskType type, TaskCommand command);
	/*!
	 * Builds a command task.
	 */
	TaskDescriptor(TaskType type, TaskLinkage link);
	/*!
	 * Creates a task from another one by copying its members.
	 */
	TaskDescriptor(const TaskDescriptor& task);
	/*!
	 * Destructor.
	 */
	virtual ~TaskDescriptor();
	/*!
	 * Gets task ID.
	 */
	TaskId get_id() const {
		return this->_id;
	}
	/*!
	 * Sets task ID: this function should not be used because TaskDescriptor
	 * already thinks about this, an id conflict might occur if the id would
	 * be set manually.
	 */
	void set_id(TaskId id) {
		this->_id = id;
	}
	/*!
	 * Gets a copy of the task typology.
	 */
	TaskType get_type() const {
		return this->_type;
	}
	/*!
	 * Sets the task type
	 */
	void set_type(TaskType type) {
		this->_type = type;
	}
	/*!
	 * Gets task link
	 */
	TaskLinkage get_link() const {
		return this->_link;
	}
	/*!
	 * Sets task link
	 */
	void set_link(TaskLinkage link) {
		this->_link = link;
	}
	/*!
	 * gets task command.
	 */
	TaskCommand get_command() const {
		return this->_command;
	}
	/*!
	 * Sets task command.
	 */
	void set_command(TaskCommand command) {
		this->_command = command;
	}
	/*!
	 * Used when looking into an array of tasks and no desired task is found.
	 */
	static TaskDescriptor getInvalidTaskDescriptor() {
		TaskDescriptor task;
		task.set_id(0);
		return task;
	}
protected:
	/*!
	 * Represents the unique reference to this task.
	 */
	TaskId _id;
	/*!
	 * Represents the type of task, it can be an executable or a bash command.
	 */
	TaskType _type;
	/*!
	 * If type is bash command, then this is the command to run.
	 */
	TaskCommand _command;
	/*!
	 * Represents the extended link to the physical resource representing
	 * the executable to launch.
	 */
	TaskLinkage _link;
private:
	friend class boost::serialization::access;
	/*!
	 * BOOST serialization function.
	 */
	template<class Archive>
	void serialize(Archive & ar, const unsigned int version) {
		ar & _id;
		ar & _type;
		ar & _command;
		ar & _link;
	}
	/*!
	 * Gets a unique id for the task.
	 */
	TaskId createID();
}; /* TaskDescriptor */
} /* middleware */

#endif
